﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MOJsdk
{
    public class Languages_ISO639_1 : DoubleDictionary<string, string>
    {
        public Languages_ISO639_1()
        { 
            LoadLanguages();
        }
        private void LoadLanguages()
        {
            Clear();

            Add("xx", "Other");
            Add("af", "Afrikaans");
            Add("ar", "Arabic");
            Add("be", "Belarusian");
            Add("bg", "Bulgarian");
            Add("my", "Burmese");
            Add("ca", "Catalan");
            Add("cs", "Czech");
            Add("cy", "Welsh");
            Add("da", "Danish");
            Add("de", "German");
            Add("dv", "Divehi");
            Add("el", "Greek");
            Add("en", "English");
            Add("es", "Spanish");
            Add("et", "Estonian");
            Add("fa", "Persian");
            Add("fi", "Finnish");
            Add("fr", "French");
            Add("ga", "Irish");
            Add("gu", "Gujarati");
            Add("he", "Hebrew");
            Add("hi", "Hindi");
            Add("hr", "Croatian");
            Add("hu", "Hungarian");
            Add("hy", "Armenian");
            Add("is", "Icelandic");
            Add("iu", "Inuktitut");
            Add("it", "Italian");
            Add("ja", "Japanese");
            Add("ka", "Georgian");
            Add("kn", "Kannada");
            Add("ko", "Korean");
            Add("kj", "Kuanyama");
            Add("ku", "Kurdish");
            Add("lo", "Laothian");
            Add("lt", "Lithuanian");
            Add("lv", "Latvian");
            Add("mk", "Macedonian");
            Add("ml", "Malayalam");
            Add("ms", "Malay");
            Add("no", "Norwegian");
            Add("nl", "Dutch");
            Add("or", "Oriya");
            Add("pa", "Punjabi");
            Add("pl", "Polish");
            Add("pt", "Portuguese");
            Add("ro", "Romanian");
            Add("ru", "Russian");
            Add("si", "Sinhalese");
            Add("sk", "Slovak");
            Add("sl", "Slovenian");
            Add("sr", "Serbian");
            Add("sw", "Swahili");
            Add("sv", "Swedish");
            Add("ta", "Tamil");
            Add("te", "Telugu");
            Add("th", "Thai");
            Add("tr", "Turkish");
            Add("uk", "Ukrainian");
            Add("vi", "Vietnamese");
            Add("yi", "Yiddish");
        }

        public string this[string Key]
        {
            get
            {
                return (string)this[Key, typeof(string)];
            }
        }
        public List<string> GetLanguages
        {
            get
            {
                List<string> list = new List<string>();

                foreach (var v in GetType2)
                    list.Add(v);

                return list;
            }
        }
    }

    public class DoubleDictionary<T, Z>
    {
        private Dictionary<T, Z> _dict1;
        private Dictionary<Z, T> _dict2;

        public DoubleDictionary()
        {
            _dict1 = new Dictionary<T, Z>();
            _dict2 = new Dictionary<Z, T>();
        }
        public void Clear()
        {
            _dict1.Clear();
            _dict2.Clear();
        }
        public bool Add(T Value1, Z Value2)
        {
            if (_dict1.ContainsKey(Value1) || _dict2.ContainsKey(Value2))
                return false;

            _dict1.Add(Value1, Value2);
            _dict2.Add(Value2, Value1);

            return true;
        }
        private bool IsHasOneType()
        { return typeof(T) == typeof(Z); }

        public object this[object Key]
        {
            get
            {
                T TKey;
                Z Zkey;

                if (IsHasOneType())
                {
                    TKey = (T)Key;
                    Zkey = (Z)Key;

                    if (_dict1.ContainsKey(TKey))
                        return _dict1[TKey];
                    if (_dict2.ContainsKey(Zkey))
                        return _dict2[Zkey];
                }

                if (Key.GetType() == typeof(T))
                    if (_dict1.ContainsKey((T)Key))
                        return _dict1[(T)Key];

                if (Key.GetType() == typeof(Z))
                    if (_dict2.ContainsKey((Z)Key))
                        return _dict2[(Z)Key];

                throw new Exception("Invalid Key");
            }
        }
        public object this[object Key, Type TheType]
        {
            get
            {
                T TKey;
                Z Zkey;

                if (IsHasOneType())
                {
                    TKey = (T)Key;
                    Zkey = (Z)Key;

                    if (_dict1.ContainsKey(TKey))
                        return _dict1[TKey];
                    if (_dict2.ContainsKey(Zkey))
                        return _dict2[Zkey];
                }

                if (TheType == typeof(T))
                    if (_dict1.ContainsKey((T)Key))
                        return _dict1[(T)Key];

                if (TheType == typeof(Z))
                    if (_dict2.ContainsKey((Z)Key))
                        return _dict2[(Z)Key];

                throw new Exception("Invalid Key");
            }
        }

        public List<T> GetType1
        {
            get
            {
                List<T> list = new List<T>();
                foreach (var v in _dict1.Keys)
                    list.Add(v);

                return list;
            }
        }
        public List<Z> GetType2
        {
            get
            {
                List<Z> list = new List<Z>();
                foreach (var v in _dict2.Keys)
                    list.Add(v);

                return list;
            }
        }
    }
}
